#include "surbasic/XmlHelper.h"
#include "surbasic/surbasic.h"

namespace SDBasic {
namespace xml {

static const char* GetText(XMLElement* elem) {
  const char* v = elem->GetText();
  return (v == NULL ? "" : v);
}

bool ParseCheckAccountXml(const char* xml, AccessToken& token) {
  XMLDocument doc;
  XMLError error = doc.Parse(xml);
  if (error != 0) {
    log_callback(LogError, "xml parse error: %s\r\n", xml);
    return false;
  }
  XMLElement* rootElement = doc.FirstChildElement("root");
  if (!rootElement) {
    log_callback(LogError, "find first element is not root.\r\n");
    return false;
  }
  XMLElement* firstElement = rootElement->FirstChildElement("resultCode");
  if (!firstElement) {
    log_callback(LogError, "result code parse error.\r\n");
    return false;
  }
  const char* first = GetText(firstElement);
  log_callback(LogDebug, "result: %s\n", first);

  XMLElement* NextElement = firstElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "webservername parse error.\r\n");
    return false;
  }
  const char* webservername = GetText(NextElement);
  log_callback(LogDebug, "webservername: %s\n", webservername);
  token.webserver = webservername;

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "servername parse error.\r\n");
    return false;
  }
  const char* servername = GetText(NextElement);
  log_callback(LogDebug, "servername: %s\n", servername);
  token.server = servername;

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "svgsservername parse error.\r\n");
    return false;
  }
  const char* svgsservername = GetText(NextElement);
  log_callback(LogDebug, "svgsservername: %s\n", svgsservername);
  token.svgserver = svgsservername;
  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "dbservername parse error.\r\n");
    return false;
  }
  const char* dbservername = GetText(NextElement);
  log_callback(LogDebug, "dbservername: %s\n", dbservername);
  token.dbserver = dbservername;
  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "privatekey parse error.\r\n");
    return false;
  }
  const char* pkname = GetText(NextElement);
  token.privatekey = pkname;
  XMLElement* NextElementChild = NextElement->NextSiblingElement();
  if (!NextElementChild) {
    log_callback(LogError, "state parse error.\r\n");
    return false;
  }

  NextElement = NextElementChild->FirstChildElement("state");
  const char* statename = GetText(NextElement);
  log_callback(LogDebug, "state key: %s\n", statename);

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "access token parse error.\r\n");
    return false;
  }
  const char* accesstokenname = GetText(NextElement);
  log_callback(LogDebug, "access token: %s\n", accesstokenname);
  token.access_token = accesstokenname;
  if (token.access_token.empty()) return false;

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "expries  parse error.\r\n");
    return false;
  }
  const char* expriesname = GetText(NextElement);
  log_callback(LogDebug, "expries: %s\n", expriesname);
  token.expires_in = atoi(expriesname);

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "refresh token  parse error.\r\n");
    return false;
  }
  const char* refreshname = GetText(NextElement);
  log_callback(LogDebug, "refresh: %s\n", refreshname);
  token.refresh_token = refreshname;
  if (token.refresh_token.empty()) return false;

  NextElement = NextElement->NextSiblingElement();
  if (!NextElement) {
    log_callback(LogError, "resource server  parse error.\r\n");
    return false;
  }
  const char* resourcename = GetText(NextElement);
  log_callback(LogDebug, "resource: %s\n", resourcename);
  token.resource_server = resourcename;

  return true;
}
}
}  // namespace
